package com.g.ocache.impl.store.entry;

import com.g.ocache.StoreEntry;

/**
 * 
 * @author zhangyf
 * @param <K>
 * @param <V>
 */
public class TtiStoreEntry<K, V> implements StoreEntry<K, V> {
	//
	private K key;
	private V value;
	protected int timeToIdle;
	protected long lastAccessTime;

	/**
	 * 
	 * @param key
	 * @param value
	 */
	public TtiStoreEntry(K key, V value) {
		this.key = key;
		this.value = value;
	}
	
	/**
	 * 
	 */
	public K getKey() {
		return key;
	}

	public V getValue() {
		//
		if(timeToIdle > 0) {
			lastAccessTime = System.currentTimeMillis();
		}
		
		//
		return value;
	}

	public boolean isExpired() {
		//
		if (timeToIdle <= 0) {
			return false;
		}
		
		//
		long now = System.currentTimeMillis();
		long expirationTime = lastAccessTime + timeToIdle * 1000L;
		return now > expirationTime;
	}
	
	/**
	 * 
	 */
	public int getTimeToIdle() {
		return timeToIdle;
	}

	public void setTimeToIdle(int timeToIdle) {
		this.timeToIdle = timeToIdle;
	}
	
	public long getLastAccessTime() {
		return lastAccessTime;
	}
	
	public void setLastAccessTime(long lastAccessTime) {
		this.lastAccessTime = lastAccessTime;
	}
	
	/**
	 * 
	 */
	public static class FactoryImpl<K, V> implements Factory<K, V> {
		//
		private int timeToIdle;

		/**
		 * 
		 */
		public FactoryImpl(int timeToIdle) {
			this.timeToIdle = timeToIdle;
		}

		/**
		 * 
		 */
		public StoreEntry<K, V> create(K key, V value) {
			//
			TtiStoreEntry<K, V> storeEntry = new TtiStoreEntry<K, V>(key, value);
			storeEntry.setTimeToIdle(timeToIdle);
			
			//
			storeEntry.setLastAccessTime(System.currentTimeMillis());
			return storeEntry;
		}
	}
}
